package com.cs.base.lib;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Action;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Predicate;


public class RxTimerUtil {

    private static CompositeDisposable mCompositeDisposable;

    /**倒计时
     * @param totalSecond
     * @param delaySecond
     * @param next
     */
    public static void startEnd(long totalSecond, long delaySecond, final IRxNext next) {
        Disposable mDisposable = Flowable.intervalRange(0, totalSecond, delaySecond, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        next.doNext(totalSecond - aLong);
                    }
                })
                .doOnComplete(new Action() {
                    @Override
                    public void run() throws Exception {
                        //倒计时完毕置为可点击状态
                        next.onFinish();
                    }
                })
                .subscribe();
        addMyDisposable(mDisposable);
    }

    /**
     * seconds秒后执行next操作
     */
    public static void timer(long seconds, final IRxNext next) {
        Observable.timer(seconds, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable disposable) {
                        addMyDisposable(disposable);
                    }

                    @Override
                    public void onNext(@NonNull Long number) {
                        if (next != null) {
                            next.doNext(number);
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        //取消订阅
                        cancel();
                    }

                    @Override
                    public void onComplete() {
                        //取消订阅
                        cancel();
                    }
                });
    }

    /**
     * 每隔seconds秒后执行next操作
     */
    public static void interval(@NonNull LifecycleOwner owner, long seconds, final IRxNext next) {
        Observable.interval(seconds, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .takeWhile(new Predicate<Long>() {
                    @Override
                    public boolean test(Long aLong) throws Throwable {
                        //LogUtils.d("Observable.interval","State="+owner.getLifecycle().getCurrentState());
                        if(owner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED
                                || owner.getLifecycle().getCurrentState() == Lifecycle.State.INITIALIZED){
                            return false;
                        }
                        return true;
                    }
                })
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable disposable) {
                        addMyDisposable(disposable);
                    }

                    @Override
                    public void onNext(@NonNull Long number) {
                        if (next != null) {
                            next.doNext(number);
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        //取消订阅
                        cancel();
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 每隔seconds秒后执行next操作,前台时执行，后台时停止
     */
    public static void intervalFront(@NonNull LifecycleOwner owner, long seconds, final IRxNext next) {
        Observable.interval(seconds, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .takeWhile(new Predicate<Long>() {
                    @Override
                    public boolean test(Long aLong) throws Throwable {
                        //LogUtils.d("Observable.interval","State="+owner.getLifecycle().getCurrentState());
                        if(owner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED
                            || owner.getLifecycle().getCurrentState() == Lifecycle.State.INITIALIZED){
                            return false;
                        }
                        return true;
                    }
                })
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable disposable) {
                        addMyDisposable(disposable);
                    }

                    @Override
                    public void onNext(@NonNull Long number) {
                        if (next != null && owner.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED) {
                            next.doNext(number);
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        //取消订阅
                        cancel();
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 取消订阅
     */
    public static void cancel() {
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
        }
        mCompositeDisposable = null;
    }

    public interface IRxNext {
        void doNext(long seconds);

        void onFinish();
    }

    private static void addMyDisposable(Disposable disposable) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }
}
